﻿using System;
using System.Collections.Generic;
using System.Text;
using SourceCode.Workflow.Client;
using SourceCode.Hosting.Client.BaseAPI;

namespace ASBCC.Workflow.K2Manager
{
    public static class K2Client
    {
        /// <summary>
        /// 将流程调整到任意节点
        /// </summary>
        /// <param name="worklistItem"></param>
        /// <param name="gotoActivity"></param>
        /// <param name="userArr"></param>
        //public static void GotoActivity(Connection connection, string serialNumber, K2AuditDestination auditDestination)
        //{
        //    WorklistItem worklistItem = connection.OpenWorklistItem(serialNumber);
        //    K2Helper.AssignXmlFields(worklistItem.ProcessInstance.XmlFields, auditDestination);
        //    ExecuteAction(worklistItem, K2ActionName.Update);
        //    worklistItem.GotoActivity(auditDestination.ActivityDestinationList[0].ActivityName);
        //}

        public static int StartProcessAndSubmit(string processName, string folio, int applicantId, SerializableDictionary dataFields, K2AuditDestination auditDestination)
        {
            int procInstID = -1;
            Connection connection = K2Client.OpenConnection();
            try
            {
                //启动流程
                procInstID = K2Client.StartProcessInstance(connection, processName, folio, applicantId, dataFields);

                //提交到下一个节点
                SourceCode.Workflow.Management.WorklistItems worklistItems = K2Admin.GetWorklistItems(processName, folio);
                if (worklistItems.Count != 1) throw new Exception(string.Format("Failed to StartProcessInstance. ProcessName={0};Filio={1};worklistItems.Count={2}", processName, folio, worklistItems.Count));
                SourceCode.Workflow.Management.WorklistItem worklistItem = worklistItems[0];

                //K2Admin.RedirectWorklistItem(worklistItem.Destination, K2Helper.GetAdminDestinationName(), worklistItem.ProcInstID, worklistItem.ActInstDestID, worklistItem.ID);
                string username = K2Helper.GetAuditUsername(worklistItem.Destination);
                connection.ImpersonateUser(username);

                string serialNumber = K2Helper.GetSerialNumber(worklistItem.ProcInstID, worklistItem.ActInstDestID);
                K2Client.ExecuteAction(connection, serialNumber, K2ActionName.Submit, auditDestination, dataFields);

                connection.RevertUser();

            }
            catch (Exception ex)
            {
                throw;
            }
            finally
            {
                connection.Close();
            }

            return procInstID;
        }

        /// <summary>
        /// 启动流程
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="processName"></param>
        /// <param name="folio"></param>
        /// <param name="applicant"></param>
        public static int StartProcessInstance(Connection connection, string processName, string folio, int applicantId, SerializableDictionary dataFields)
        {
            ProcessInstance procInst = connection.CreateProcessInstance(processName);
            procInst.Folio = folio;

            K2Helper.AssignDataFields(procInst.DataFields, dataFields);
            K2Helper.AssignXmlFields(procInst.XmlFields, new K2AuditDestination(string.Empty, new int[] { applicantId }));
            connection.StartProcessInstance(procInst, true);
            return procInst.ID;
        }

        /// <summary>
        /// 对worklistItem执行指定动作
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="actionName"></param>
        /// <param name="serialNumber"></param>
        /// <param name="userArr"></param>
        public static void ExecuteAction(Connection connection, string serialNumber, string actionName, K2AuditDestination auditDestination, SerializableDictionary dataFields)
        {
            WorklistItem worklistItem = connection.OpenWorklistItem(serialNumber);
            K2Helper.AssignDataFields(worklistItem.ProcessInstance.DataFields, dataFields);
            K2Helper.AssignXmlFields(worklistItem.ProcessInstance.XmlFields, auditDestination);
            ExecuteAction(worklistItem, actionName);
        }

        public static void GetDataAndXmlFields(Connection connection, int procInstId, out SerializableDictionary dataFieldDict, out K2AuditDestination auditDestination)
        {
            ProcessInstance procInst = connection.OpenProcessInstance(procInstId);
            dataFieldDict = K2Helper.ConvertDataFieldsToDictionary(procInst.DataFields);
            auditDestination = K2Helper.ConvertXmlFieldsToAuditDestination(procInst.XmlFields);
        }

        public static void UpdateDataAndXmlFields(Connection connection, int procInstId, K2AuditDestination auditDestination, SerializableDictionary dataFields)
        {
            ProcessInstance procInst = connection.OpenProcessInstance(procInstId);
            K2Helper.AssignDataFields(procInst.DataFields, dataFields);
            K2Helper.AssignXmlFields(procInst.XmlFields, auditDestination);
            procInst.Update();

            
        }

       

        /// <summary>
        /// 对worklistItem执行指定动作
        /// </summary>
        /// <param name="worklistItem"></param>
        /// <param name="actionName"></param>
        private static void ExecuteAction(WorklistItem worklistItem, string actionName)
        {
            foreach (SourceCode.Workflow.Client.Action action in worklistItem.Actions)
            {
                if (action.Name == actionName)
                {
                    action.Execute(true);
                }
            }
        }

        public static Connection OpenConnection()
        {
            Connection conn = new Connection();
            SCConnectionStringBuilder sb = new SCConnectionStringBuilder();
            sb.Authenticate = true;
            sb.EncryptedPassword = false;
            sb.Host = K2Config.K2Server;
            sb.Integrated = true;
            sb.IsPrimaryLogin = true;
            sb.Password = K2Config.K2AdminPassword;
            sb.Port = Convert.ToUInt32(K2Config.K2Port);
            sb.SecurityLabelName = "K2";
            sb.UserID = K2Config.K2AdminName;
            sb.WindowsDomain = K2Config.K2DomainName;

            string connStr = sb.ToString();
            conn.Open(K2Config.K2Server, connStr);

            return conn;
        }

       
    }
}
